package com.gengzp.rpc.core;

import com.gengzp.rpc.exception.RpcException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.BeanFactory;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * @ClassName RpcCoreInvocationProcessor
 * @Description rpc核心调用处理器
 * @Author gengzp
 * @Date 2025/8/21 18:21
 */
public class RpcCoreInvocationHandler implements InvocationHandler {

    private static final Logger logger = LoggerFactory.getLogger(RpcCoreInvocationHandler.class);

    /**
     * 要调用的远程服务名
     */
    private final String remoteServiceName;

    /**
     * bean 工厂
     */
    private final BeanFactory beanFactory;

    /**
     * 远程调用消费者端核心方法
     */
    private static RpcConsumerCoreFunc rpcConsumerCoreFunc = null;

    /**
     * 远程调用请求标识核心方法
     */
    private static RpcRequestIdentificationCoreFunc rpcRequestIdentificationCoreFunc = null;

    /**
     * 远程事务核心方法
     */
    private static RpcRemoteTransactionCoreFunc rpcRemoteTransactionCoreFunc = null;

    public RpcCoreInvocationHandler(String remoteServiceName, BeanFactory beanFactory) {
        this.remoteServiceName = remoteServiceName;
        this.beanFactory = beanFactory;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws RpcException {
        long remoteCallStartTime = System.currentTimeMillis();

        // 处理bean的初始化
        processBeanInitialization();

        try {
            logger.info("[Consumer] 发起远程调用, 远程服务名: {}, 远程方法: {}.{}()",
                    remoteServiceName, proxy.getClass().getInterfaces()[0].getSimpleName(), method.getName());

            // 执行消费者核心逻辑
            Object result = rpcConsumerCoreFunc.doExecuteRemoteCallConsumer(remoteServiceName, proxy, method, args);

            // 若当前请求被远程事务管理, 则处理事务提交
            if (rpcRequestIdentificationCoreFunc.getCurrentRequestIdentification().getInitialRequestFlag()) {
                rpcRemoteTransactionCoreFunc.doCommitRemoteTransaction(
                        remoteServiceName,
                        proxy.getClass().getInterfaces()[0].getSimpleName(),
                        method,
                        args);
            }

            logger.info("[Consumer] 远程调用执行完成, 耗时: {}ms", System.currentTimeMillis() - remoteCallStartTime);
            return result;
        } catch (Exception e) {
            logger.error("[Consumer] 远程调用执行失败, 耗时: {}ms, 失败信息: {}",
                    System.currentTimeMillis() - remoteCallStartTime, e.getMessage());
            throw RpcException.get(e.getMessage());
        }
    }

    /**
     * 处理 bean 的初始化逻辑
     */
    private void processBeanInitialization() {
        if (rpcConsumerCoreFunc == null) {
            rpcConsumerCoreFunc = beanFactory.getBean(RpcConsumerCoreFunc.class);
        }
        if (rpcRequestIdentificationCoreFunc == null) {
            rpcRequestIdentificationCoreFunc = beanFactory.getBean(RpcRequestIdentificationCoreFunc.class);
        }
        if (rpcRemoteTransactionCoreFunc == null) {
            rpcRemoteTransactionCoreFunc = beanFactory.getBean(RpcRemoteTransactionCoreFunc.class);
        }
    }

}
